home *** CD-ROM | disk | FTP | other *** search
/ No Fragments Archive 12: Textmags & Docs / nf_archive_12.iso / MAGS / SOURCES / ATARI_SRC.ZIP / atari source / AHDI / TTFHDX / EPART.C < prev    next >
Encoding:
C/C++ Source or Header  |  2001-02-09  |  10.1 KB  |  321 lines

  1. /* epart.c */
  2.  
  3. /*
  4.  * 14-Sep-89    ml.    Modified to use Rwabs() instead of hread()
  5.  *            and hwrite().  Will handle both SCSI and ACSI
  6.  *            drives.
  7.  * 21-Sep-89    ml.    Modified to handle big partitions (>=16Mb).
  8.  */
  9.  
  10. #include <obdefs.h>
  11. #include <osbind.h>
  12. #include "fhdx.h"
  13. #include "define.h"
  14. #include "part.h"
  15. #include "bsl.h"
  16. #include "addr.h"
  17. #include "lrwabs.h"
  18.  
  19. extern SECTOR *badbuf;
  20. extern long bslsiz;
  21.  
  22. extern long maxpsiz;
  23. static PART *pinfo;        /* -> partition block */
  24.  
  25. /*
  26.  *  Place partition headers at the appropiate sectors.
  27.  *    Input:
  28.  *        pdev - physical device partitions belong to.
  29.  *        part - partition structure containing the partitions'
  30.  *               information.
  31.  *        spc - sectors per cylinder.
  32.  *    Return:
  33.  *        OK - if everything is fine.
  34.  *        ERROR - error occurs when testing header sectors.
  35.  *    Comments:
  36.  *        Making sure that the headers occupy consecutive good 
  37.  *    sectors.  If necessary, sizes of partitions are adjusted to 
  38.  *    achieve this purpose.
  39.  *        If any size adjustment make a partition bigger than
  40.  *    the maximum size, the partition will be adjusted to the maximum
  41.  *    size leaving the excessive sectors wasted.
  42.  */
  43. pheader(pdev, part, spc)
  44. int pdev;    /* physical device number */
  45. PART *part;    /* partition info */
  46. int spc;
  47. {
  48.     /* Maximum sizes for FAT, root directory and header <in sectors> */
  49.     long  maxdent;        /* max num entries in root dir */
  50.     long  start;        /* starting sector number of a partition */
  51.     long  entries, nument();    /* num entries in BSL */
  52.     long  psiz, newsiz;        /* size of modified partition */
  53.     unsigned int  maxfsiz, maxdsiz, hdrsiz, sratio;
  54.     int  pno;            /* partition being dealt with */
  55.     int  done;            /* tell if location of header is found */
  56.     int  moved;            /* num sectors header has been moved */
  57.     int  curr;            /* current sector of header being checked */
  58.     int  ret;            /* return code from testing header sectors */
  59.     long currbsiz;        /* BSL size b4 pheader is executed */
  60.     
  61.     /* Get the BSL ready for later */
  62.     entries = nument(MEDIA);
  63.     sortbsl(entries);
  64.     currbsiz = bslsiz;        /* save current size of BSL */
  65.     
  66.     /* Determine actual sizes and starting sectors for all partitions */
  67.     for (pno = 0; pno < NPARTS; pno++) {
  68.         
  69.         /* Check if partition exists.  If it doesn't, move on to next one */
  70.         if (!(part[pno].p_flg & P_EXISTS))
  71.             continue;
  72.  
  73.         /* Partition 0 starts right after the BSL.  The rest starts right
  74.            after its previous partition */
  75.     if (pno == 0)
  76.         start = 1 + currbsiz;
  77.     else
  78.         start = part[pno-1].p_st + part[pno-1].p_siz;
  79.  
  80.     sratio = 1;        /* assume log sect size = phys sect size */
  81.     psiz = part[pno].p_siz;    /* => partition size = # phys sector */
  82.     
  83.     /* 
  84.      * if partition is too big, double sector size until 
  85.      * number of log sectors <= maxpsiz 
  86.      */
  87.     while ((psiz / sratio) > maxpsiz)
  88.         sratio <<= 1;
  89.         
  90.     psiz /= sratio;        /* # log sectors in partition */
  91.     
  92.         /* Detail of calculations in part.c dopart() */
  93.         /* find max FAT size */
  94.         maxfsiz = ((psiz >> 1) + 2) / (256*sratio) + 1;
  95.         /* find max root dir entries */
  96.         maxdent = (part[pno].p_siz/ 80) + (sratio<<4 - 1) & ~(sratio<<4 - 1);
  97.         /* find max root dir size */
  98.         maxdsiz = maxdent / (16*sratio);
  99.     
  100.         /*--------------------------------------------------------------*
  101.          * Biggest possible header for a partition <in # phys sectors>     *
  102.          *    =  Boot Sector + 2 FATs + Root Dir             *
  103.          *--------------------------------------------------------------*/
  104.         hdrsiz = sratio * (1 + (maxfsiz * 2) + maxdsiz);
  105.     
  106.     /*-----------------------------------------------------------------*
  107.      * Look for a chunk of sectors starting at "start" (or after, but  *
  108.      * as close as possible) which is big enough to hold the biggest   *
  109.      * possible header.                           *
  110.      *-----------------------------------------------------------------*/
  111.     done = 0;       /* assume correct location not found yet */
  112.     moved = 0;    /* assume header has not been moved */
  113.     while (!done) {
  114.         /*----------------------------------------------------------*
  115.          * Find out if header contains any bad sectors by checking    *
  116.          * range of sectors to be occupied by the header against    *
  117.          * the BSL.                            *
  118.          *----------------------------------------------------------*/
  119.         for (curr = 0; curr < hdrsiz; curr++) {
  120.             if (srchbsl(start+curr, entries) == YES)
  121.                 break;
  122.         }
  123.         
  124.         if (curr < hdrsiz) {    /* bad sector found in header */
  125.             /* move header to start after the bad sector */
  126.             moved += curr + 1;
  127.             start += curr + 1;
  128.         } else {            /* header is fine as it is */
  129.             if ((ret = testhdr(pdev, start, hdrsiz, spc)) < 0)
  130.                 return ERROR;
  131.             if (ret) {    /* Some bad sectors found in header */
  132.                 entries = nument(MEDIA);
  133.                 sortbsl(entries);
  134.             } else {    /* all sectors belong to header are good */
  135.                 done = 1;
  136.             }
  137.         }
  138.     }
  139.     
  140.     if (moved) {    /* header has been moved */
  141.         /*-------------------------------------------------------*
  142.          * Expand previous partition (except if the current one  *
  143.          * is partition 0, then there is no previous partition), *
  144.          * and enforce maximum partition size on it.         *
  145.          *-------------------------------------------------------*/
  146.         if (pno > 0) {
  147.         part[pno-1].p_siz += moved;
  148.         }
  149.             
  150.         /* Shrink size of current partition */
  151.         part[pno].p_siz -= moved;
  152.     }
  153.     
  154.     /* Where current partition should start */
  155.     part[pno].p_st = start;
  156.     }
  157.     
  158.     /* last existing partition has to sacrifice some 
  159.        space for the BSL.                */
  160.     for (pno = NPARTS-1; pno >= 0; pno--) {
  161.         if (part[pno].p_flg & P_EXISTS) {
  162.         part[pno].p_siz -= (currbsiz + 1);
  163.         break;
  164.     }
  165.     }
  166.  
  167.     /* have to move 1st GEM partition if BSL has been expanded,
  168.        and shrink it's size too */
  169.     if (bslsiz > currbsiz) {        /* BSL becomes bigger? */
  170.         if (part[0].p_st == currbsiz + 1) {
  171.         part[0].p_st = bslsiz + 1;
  172.         part[0].p_siz -= (bslsiz - currbsiz);
  173.     }
  174.     }
  175.     return OK;    /* everything is fine */
  176. }
  177.  
  178.  
  179.  
  180. /*
  181.  *  Make sure that sectors assigned to a partition header are GOOD.
  182.  *    Input:
  183.  *        pdev - physical device number partition belongs to.
  184.  *        start - starting (physical) sector number header starts.
  185.  *        hdrsiz - number of sectors header occupies.
  186.  *        spc - sectors per cylinder.
  187.  *    Return:
  188.  *        OK - if all sectors in header are good.
  189.  *        positive number - if entries are added to BSL in testing
  190.  *                    the header.
  191.  *        ERROR - if somewhere the process went wrong.
  192.  *    Comments:
  193.  *        Bad Sectors found are added as USER bad sectors.  
  194.  *    First, because we can't expand the VENDOR list while preserving
  195.  *    the USER list.  Second, this is ok, because even if the USER list
  196.  *    is full, the user should reformat the disk anyway, and if the
  197.  *    sector is REALLY bad, it would be discovered again then.
  198.  */
  199. testhdr(pdev, start, hdrsiz, spc)
  200. int pdev;
  201. SECTOR start;
  202. unsigned int hdrsiz;
  203. int spc;
  204. {
  205.     long olderr, crerr(), ret;
  206.     long size, pattern;
  207.     extern long longrandom();
  208.     int sectcnt;
  209.     int nbad, clean=1;
  210.     SECTOR sect;
  211.     char *buf;        /* buffer with test data */
  212.     
  213.     olderr = Setexc(0x101, crerr);    /* Handle critical error ourselves */
  214.     
  215.     size = (long)hdrsiz * 512;
  216.     if ((buf = (char *)Malloc(size)) <= 0) {
  217.         err(nomemory);
  218.         ret = NOMEM;
  219.         goto wrapup;
  220.     }
  221.     
  222.     /*
  223.      * Try to write to header's sectors.
  224.      */
  225.     pattern = longrandom();
  226.     fillbuf(buf, size, pattern);
  227.     sectcnt = hdrsiz;
  228.     sect = start;
  229.     nbad = 0;
  230.     if (Lrwabs(PHYSWRT, buf, sectcnt, sect, pdev+2) != 0) {
  231.         clean = 0;
  232.         
  233.         while (sectcnt) {
  234.         if (Lrwabs(PHYSWRT, 0L, 1, sect, pdev+2) != 0) {
  235.                 if (sect < spc) {
  236.             ret = err(cyl0bad);
  237.             goto wrapup;
  238.         }
  239.                     
  240.                  *(badbuf+nbad) = sect;    /* store bad sector num */
  241.                  nbad++;
  242.                     
  243.                 /* buffer is filled up, have to add bad sectors
  244.                    found so far to the BSL before continuing.   */
  245.                 if (nbad == WARNBADSECTS) {
  246.                        if ((ret=addbsl(pdev, VENDOR, nbad)) < 0) {
  247.             if (ret == INVALID)
  248.                 err(cruptbsl);
  249.                            goto wrapup;
  250.                        }
  251.                        nbad = 0;    /* start counting again */
  252.                 }
  253.             }
  254.             sect++;
  255.             sectcnt--;
  256.         }
  257.         if (nbad) {    /* there are bad sectors found not added to BSL yet */
  258.             if ((ret = addbsl(pdev, VENDOR, nbad)) < 0) {
  259.                 if (ret == INVALID)
  260.                     err(cruptbsl);
  261.                 goto wrapup; 
  262.             }
  263.         }
  264.     }
  265.     
  266.     /* Try to read header's sectors */
  267.     sectcnt = hdrsiz;
  268.     sect = start;
  269.     nbad = 0;
  270.     if (Lrwabs(PHYSREAD, buf, sectcnt, sect, pdev+2) != 0) {
  271.         clean = 0;
  272.         
  273.         while (sectcnt) {
  274.         if (Lrwabs(PHYSREAD, buf, 1, sect, pdev+2) != 0) {
  275.                 if (sect < spc) {
  276.             ret = err(cyl0bad);
  277.             goto wrapup;
  278.         }
  279.                     
  280.                  *(badbuf+nbad) = sect;    /* store bad sector num */
  281.                  nbad++;
  282.                     
  283.                 /* buffer is filled up, have to add bad sectors
  284.                    found so far to the BSL before continuing.   */
  285.                 if (nbad == WARNBADSECTS) {
  286.                        if ((ret=addbsl(pdev, VENDOR, nbad)) < 0) {
  287.             if (ret == INVALID)
  288.                 err(cruptbsl);
  289.                            goto wrapup;
  290.                        }
  291.                        nbad = 0;    /* start counting again */
  292.                 }
  293.             }
  294.             sect++;
  295.             sectcnt--;
  296.         }
  297.         if (nbad) {    /* there are bad sectors found not added to BSL yet */
  298.             if ((ret = addbsl(pdev, VENDOR, nbad)) < 0) {
  299.                 if (ret == INVALID)
  300.                     err(cruptbsl);
  301.                 goto wrapup; 
  302.             }
  303.         }
  304.     }
  305. wrapup:
  306.     if (buf > 0L)  Mfree((long)buf);
  307.     Setexc(0x101, olderr);
  308.     
  309.     if (ret < 0)
  310.         return (int)ret;
  311.         
  312.     if (!clean) {
  313.         wrbsl(pdev);    /* write new bsl back to disk */
  314.         return 1;
  315.     }
  316.         
  317.     return OK;
  318. }
  319.  
  320.  
  321.